<template>
  <div ref="iconSelectRef" :style="{ width: width }">
    <el-popover :visible="popoverVisible" :width="width" placement="bottom-end">
      <template #reference>
        <div @click="togglePopover">
          <slot>
            <el-input v-model="selectedIcon" readonly placeholder="点击选择图标" class="reference">
              <template #prepend>
                <template v-if="isLocalSvg">
                  <svg-icon :name="selectedIcon" />
                </template>
                <template v-else>
                  <el-icon v-if="selectedIcon">
                    <component :is="selectedIcon" />
                  </el-icon>
                </template>
              </template>
              <template #suffix>
                <!-- 清空按钮 -->
                <el-icon v-if="selectedIcon" style="margin-right: 8px" @click.stop="clearSelectedIcon">
                  <ep-CircleClose />
                </el-icon>

                <el-icon
                  :style="{
                    transform: popoverVisible ? 'rotate(180deg)' : 'rotate(0)',
                    transition: 'transform .5s'
                  }"
                >
                  <ep-ArrowDown @click.stop="togglePopover" />
                </el-icon>
              </template>
            </el-input>
          </slot>
        </div>
      </template>

      <!-- 图标选择弹窗 -->
      <div ref="popoverContentRef">
        <el-input v-model="filterText" placeholder="搜索图标" clearable @input="filterIcons" />
        <el-tabs v-model="activeTab" @tab-click="handleTabClick">
          <el-tab-pane label="本地 SVG 图标" name="svg">
            <el-scrollbar height="300px">
              <ul class="icon-grid">
                <li v-for="icon in filteredSvgIcons" :key="'svg-' + icon" class="icon-grid-item" @click="selectIcon(icon)">
                  <el-tooltip :content="icon" placement="bottom" effect="light">
                    <svg-icon :name="icon" />
                  </el-tooltip>
                </li>
              </ul>
            </el-scrollbar>
          </el-tab-pane>
          <el-tab-pane label="Element 图标" name="ep">
            <el-scrollbar height="300px">
              <ul class="icon-grid">
                <li v-for="icon in filteredEpIcons" :key="icon" class="icon-grid-item" @click="selectIcon(icon)">
                  <el-icon>
                    <component :is="icon" />
                  </el-icon>
                </li>
              </ul>
            </el-scrollbar>
          </el-tab-pane>
          <el-tab-pane label="AntDesign 图标" name="ad">
            <el-scrollbar height="300px">
              <ul class="icon-grid">
                <li v-for="icon in filteredAdIcons" :key="icon" class="icon-grid-item" @click="selectIcon(icon)">
                  <el-icon>
                    <component :is="icon" />
                  </el-icon>
                </li>
              </ul>
            </el-scrollbar>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-popover>
  </div>
</template>

<script lang="ts" setup>
import { onClickOutside } from '@vueuse/core'

const selectedIcon = defineModel<string>({ default: '' })

withDefaults(defineProps<{ width?: string }>(), { width: '500px' })

const iconSelectRef = ref()
const popoverContentRef = ref()

const popoverVisible = ref(false)
const activeTab = ref<'ep' | 'ad' | 'svg'>('ep')

const globalProperties = getCurrentInstance().appContext.config.globalProperties

const svgIcons = ref<string[]>([])
const epIconKeys = ref<string[]>(globalProperties.$epIconKeys)
const adIconKeys = ref<string[]>(globalProperties.$adIconKeys)

const filterText = ref('')
const filteredSvgIcons = ref<string[]>([])
const filteredEpIcons = ref<string[]>(epIconKeys.value)
const filteredAdIcons = ref<string[]>(adIconKeys.value)

const isLocalSvg = computed(() => {
  // return selectedIcon.value && selectedIcon.value.startsWith('svg-')
  return selectedIcon.value && !selectedIcon.value.startsWith('ep-') && !selectedIcon.value.startsWith('ad-')
})

function loadIcons() {
  const icons = import.meta.glob('@/assets/icons/*.svg')
  for (const path in icons) {
    const iconName = path.replace(/.*\/(.*)\.svg$/, '$1')
    svgIcons.value.push(iconName)
  }
  filteredSvgIcons.value = svgIcons.value
}

function filterIcons() {
  if (activeTab.value === 'svg') {
    filteredSvgIcons.value = filterText.value
      ? svgIcons.value.filter(icon => icon.toLowerCase().includes(filterText.value.toLowerCase()))
      : svgIcons.value
  } else if (activeTab.value === 'ep') {
    filteredEpIcons.value = filterText.value
      ? epIconKeys.value.filter(icon => icon.toLowerCase().includes(filterText.value.toLowerCase()))
      : epIconKeys.value
  } else {
    filteredAdIcons.value = filterText.value
      ? adIconKeys.value.filter(icon => icon.toLowerCase().includes(filterText.value.toLowerCase()))
      : adIconKeys.value
  }
}

async function selectIcon(icon: string) {
  selectedIcon.value = icon
  await nextTick()
  popoverVisible.value = false
}

function togglePopover() {
  popoverVisible.value = !popoverVisible.value
}

onClickOutside(iconSelectRef, () => (popoverVisible.value = false), {
  ignore: [popoverContentRef]
})

function handleTabClick(tabPane: any) {
  activeTab.value = tabPane.paneName
  filterIcons()
}

function clearSelectedIcon() {
  selectedIcon.value = ''
}

onMounted(() => {
  loadIcons()
  if (selectedIcon.value) {
    if (selectedIcon.value.startsWith('ad-')) {
      activeTab.value = 'ad'
    } else if (selectedIcon.value.startsWith('ep-')) {
      activeTab.value = 'ep'
    } else {
      activeTab.value = 'svg'
    }
  }
})
</script>
<style lang="scss" scoped>
.reference :deep(.el-input__wrapper),
.reference :deep(.el-input__inner) {
  cursor: pointer;
}

.icon-grid {
  display: flex;
  flex-wrap: wrap;
}

.icon-grid-item {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  margin: 4px;
  cursor: pointer;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  transition: all 0.3s;
}

.icon-grid-item:hover {
  border-color: #4080ff;
  transform: scale(1.2);
}
</style>
